/**
 * 
 */
package fr.aprr.geoloc.client.view;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.gflot.client.DataPoint;
import com.googlecode.gflot.client.PlotModel;
import com.googlecode.gflot.client.Series;
import com.googlecode.gflot.client.SeriesHandler;
import com.googlecode.gflot.client.SimplePlot;
import com.googlecode.gflot.client.event.PlotClickListener;
import com.googlecode.gflot.client.event.PlotHoverListener;
import com.googlecode.gflot.client.event.PlotItem;
import com.googlecode.gflot.client.event.PlotPosition;
import com.googlecode.gflot.client.jsni.Plot;
import com.googlecode.gflot.client.options.AbstractAxisOptions.AxisPosition;
import com.googlecode.gflot.client.options.AxisOptions;
import com.googlecode.gflot.client.options.CrosshairOptions;
import com.googlecode.gflot.client.options.CrosshairOptions.Mode;
import com.googlecode.gflot.client.options.GlobalSeriesOptions;
import com.googlecode.gflot.client.options.GridOptions;
import com.googlecode.gflot.client.options.LegendOptions;
import com.googlecode.gflot.client.options.SelectionOptions;
import com.googlecode.gflot.client.options.LegendOptions.LegendPosition;
import com.googlecode.gflot.client.options.LineSeriesOptions;
import com.googlecode.gflot.client.options.PlotOptions;
import com.googlecode.gflot.client.options.PointsSeriesOptions;
import com.googlecode.gflot.client.options.SelectionOptions.SelectionMode;
import com.googlecode.gflot.client.options.TimeSeriesAxisOptions.TickTimeUnit;
import com.googlecode.gflot.client.options.TimeSeriesAxisOptions;
import com.sencha.gxt.widget.core.client.info.Info;

import fr.aprr.geoloc.client.service.DtoServices;
import fr.aprr.geoloc.client.service.DtoServicesAsync;
import fr.aprr.geoloc.shared.dto.PointDto;

/**
 * @author PHAM
 *
 */
public class FlotChart extends Composite{

	private static FlotChartUiBinder uiBinder = GWT
			.create(FlotChartUiBinder.class);

	private DtoServicesAsync dtoServices = GWT.create(DtoServices.class);

	interface FlotChartUiBinder extends UiBinder<Widget, FlotChart> {
	}

	/**
	 * Because this class has a default constructor, it can be used as a binder
	 * template. In other words, it can be used in other *.ui.xml files as
	 * follows: <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
	 * xmlns:g="urn:import:**user's package**">
	 * <g:**UserClassName**>Hello!</g:**UserClassName> </ui:UiBinder> Note that
	 * depending on the widget that is used, it may be necessary to implement
	 * HasHTML instead of HasText.
	 */

	@UiField(provided = true)
	SimplePlot plot;

	@UiField
	Label hoverPoint;

	@UiField
	Label cursorPosition;

	public FlotChart() {
		System.out.println("Display Chart");

		// Plot model
		PlotModel model = new PlotModel();

		// Option
		PlotOptions plotOption = PlotOptions.create();

		// plotOption.setLegendOptions(LegendOptions.create().setBackgroundOpacity(0).setPosition(LegendPosition.NORTH_WEST));

		// Option Definir
		plotOption
				.setGlobalSeriesOptions(GlobalSeriesOptions
						.create()
						.setLineSeriesOptions(
								LineSeriesOptions.create().setLineWidth(1)
										.setShow(true))
						.setPointsOptions(
								PointsSeriesOptions.create().setRadius(2)
										.setShow(true)));

		// Select selection
		plotOption.setSelectionOptions(SelectionOptions.create()
				.setMode(SelectionMode.XY).setColor("red"));

		// tracking
		plotOption.setCrosshairOptions(CrosshairOptions.create()
				.setMode(Mode.X));

		// Zoom position

		// Ajoueter XY-Axis

		plotOption.addYAxisOptions(TimeSeriesAxisOptions.create()
				.setTickSize(15, TickTimeUnit.MINUTE)
				.setTimeZone(TimeSeriesAxisOptions.TIME_ZONE_BROWSER_KEY));

		// Option grid
		plotOption.setGridOptions(GridOptions.create().setHoverable(true)
				.setClickable(true));

		// Generer Plot
		plot = new SimplePlot(model, plotOption);

		// Generer BD
		// generateData();
		getData();

		// Generer Popup
		final PopupPanel popup = new PopupPanel();
		final Label label = new Label();
		popup.add(label);

		// Action Hover Popup
		plot.addHoverListener(new PlotHoverListener() {

			public void onPlotHover(Plot plot, PlotPosition position,
					PlotItem item) {
				// TODO Auto-generated method stub

				if (position != null) {
					cursorPosition.addStyleName("pad-text");
					cursorPosition.setText("Position : {x=" + position.getX()
							+ ", y=" + position.getY() + "}");
				}
				if (item != null) {
					String text = "x: " + item.getDataPoint().getX() + ", y: "
							+ item.getDataPoint().getY();
					hoverPoint.addStyleName("pad-text");
					hoverPoint.setText(text);

					label.setText(text);
					popup.setPopupPosition(item.getPageX() + 10,
							item.getPageY() - 25);
					popup.show();
				} else {
					hoverPoint.setText("vide");
					popup.hide();
				}

			}
		}, false);

		// Action click
		plot.addClickListener(new PlotClickListener() {

			public void onPlotClick(Plot plot, PlotPosition position,
					PlotItem item) {
				// TODO Auto-generated method stub
				plot.unhighlight();
				if (null != item) {
					plot.highlight(item.getSeries(), item.getDataPoint());
				}
			}
		}, false);

		// Widget
		initWidget(uiBinder.createAndBindUi(this));

	}

	public FlotChart(String firstName) {
		initWidget(uiBinder.createAndBindUi(this));

		// Can access @UiField after calling createAndBindUi
		System.out.println("FlotChart(String firstName)");
	}

	public void generateData() {

		SeriesHandler ottawaSeries = plot.getModel().addSeries(
				Series.of("Vehicule 1").setColor("red"));

		// Add data

		ottawaSeries.add(DataPoint.of(1, Date.UTC(110, 2, 1, 0, 5, 0)));
		ottawaSeries.add(DataPoint.of(2, Date.UTC(110, 2, 1, 0, 10, 0)));
		ottawaSeries.add(DataPoint.of(2.1, Date.UTC(110, 2, 1, 0, 15, 0)));
		ottawaSeries.add(DataPoint.of(3.2, Date.UTC(110, 2, 1, 0, 0, 0)));
		ottawaSeries.add(DataPoint.of(3.3, Date.UTC(110, 2, 1, 1, 5, 0)));
		ottawaSeries.add(DataPoint.of(3.4, Date.UTC(110, 2, 1, 1, 10, 0)));
		ottawaSeries.add(DataPoint.of(3.5, Date.UTC(110, 2, 1, 1, 15, 0)));
		ottawaSeries.add(DataPoint.of(8, Date.UTC(110, 2, 1, 1, 20, 0)));
		ottawaSeries.add(DataPoint.of(9, Date.UTC(110, 2, 1, 1, 25, 0)));
		ottawaSeries.add(DataPoint.of(10, Date.UTC(110, 2, 1, 2, 0, 0)));
		ottawaSeries.add(DataPoint.of(11, Date.UTC(110, 2, 1, 2, 5, 0)));
		ottawaSeries.add(DataPoint.of(12, Date.UTC(110, 2, 1, 2, 10, 0)));

	}

	@SuppressWarnings("deprecation")
	private void getData() {
		// TODO Auto-generated method stub
		dtoServices
				.getAllPoint(new AsyncCallback<Map<Integer, List<PointDto>>>() {

					public void onSuccess(Map<Integer, List<PointDto>> listPoint) {
						// TODO Auto-generated method stub

						for (Map.Entry<Integer, List<PointDto>> entry : listPoint
								.entrySet()) {

							System.out.println("Key = " + entry.getKey()
									+ ", Value = " + entry.getValue().size());

							SeriesHandler series = plot.getModel().addSeries(
									Series.of(entry.getKey().toString()));

							for (PointDto point : entry.getValue()) {
								series.add(DataPoint.of(point.getPk(), Date
										.UTC(2013, 8, 11, point.getHorodate()
												.getHours(), point
												.getHorodate().getMinutes(),
												point.getHorodate()
														.getSeconds())));
							}

						}
						
						plot.redraw();
					}

					public void onFailure(Throwable arg0) {
						// TODO Auto-generated method stub
						Info.display("Flot Chart", "Get points eurrer");
					}
				});
	}

}
